#region Namespace References

using System;
using DynConDevCorp.OpenArch.SmartData.Core;
using DynConDevCorp.OpenArch.SmartData.Interfaces;
using DynConDevCorp.OpenArch.SmartData.Interfaces.Attributes;
using DynConDevCorp.OpenArch.SmartData.Interfaces.EventArgClasses;

#endregion

namespace DynConDevCorp.OpenArch.SmartData.Samples.SimpleInvoicing
{
    public class Invoice : SmartEntity
    {
        #region Constructors

        public Invoice()
        {
            ////RegisterField("InvoiceDate", InvoiceDate);
            ////RegisterField("InvoiceID", InvoiceID);
            ////RegisterField("InvoiceNumber", InvoiceNumber);
            ////RegisterField("Items", Items);
            ////RegisterField("ItemsTotalPrice", ItemsTotalPrice);
            ////RegisterField("ItemsTotalTax", ItemsTotalTax);
            ////RegisterField("ItemsTotalWeight", ItemsTotalWeight);
            ////RegisterField("Shipping", Shipping);
            ////RegisterField("ShippingRate", ShippingRate);
            ////RegisterField("TaxRate", TaxRate);
            ////RegisterField("InvoiceTotal", InvoiceTotal);
///
            //           Items.CollectionChanged += Items_CollectionChanged;
            ItemsTotalPrice.ValueChanged += Recalculate_Tax;
            ItemsTotalTax.ValueChanged += Recalculate_Total;
            ItemsTotalWeight.ValueChanged += Recalculate_Shipping;
            ItemsTotalTax.ValueChanged += Recalculate_Total;
            ShippingRate.ValueChanged += Recalculate_Shipping;
            TaxRate.ValueChanged += Recalculate_Tax;
        }

        ////void Items_CollectionChanged(object sender, CollectionChangedEventArgs e)
        ////{
        ////    InvoiceLineItem lineItem = e.Item as InvoiceLineItem;
        ////    switch (e.ChangeType)
        ////    {
        ////        case CollectionChangedEventArgs.CollectionChangeType.Added:
        ////            ItemsTotalPrice.Value += lineItem.ExtendedPrice.Value;
        ////            ItemsTotalWeight.Value += lineItem.Weight.Value;
        ////            break;
        ////        case CollectionChangedEventArgs.CollectionChangeType.Removed:
        ////            ItemsTotalPrice.Value -= lineItem.ExtendedPrice.Value;
        ////            ItemsTotalWeight.Value -= lineItem.Weight.Value;
        ////            break;
        ////        case CollectionChangedEventArgs.CollectionChangeType.Cleared:
        ////            ItemsTotalPrice.Value = 0.0M;
        ////            ItemsTotalWeight.Value = 0.0M;
        ////            break;
        ////    }
        ////}

        void Recalculate_Tax(object sender, ValueChangedEventArgs<decimal> e)
        {
            ItemsTotalTax.Value = ItemsTotalPrice.Value * TaxRate.Value;
        }

        void Recalculate_Shipping(object sender, ValueChangedEventArgs<decimal> e)
        {
            Shipping.Value = ItemsTotalWeight.Value * ShippingRate.Value;
        }

        void Recalculate_Total(object sender, ValueChangedEventArgs<decimal> e)
        {
            InvoiceTotal.Value = ItemsTotalPrice.Value + ItemsTotalTax.Value + Shipping.Value;
        }

        public void AddItem(InvoiceLineItem lineItem)
        {
            lineItem.LineNumber.Value = Items.Count.Value + 1;
            Items.Add(/*lineItem.LineNumber.Value, */ lineItem);
            lineItem.ExtendedPrice.ValueChanged += ExtendedPrice_ValueChanged;
        }

        void ExtendedPrice_ValueChanged(object sender, ValueChangedEventArgs<decimal> e)
        {
            ItemsTotalPrice.Value += (e.NewValue - e.OldValue);
        }

        #endregion

        #region Public Instance Properties

        [AutoField]
        public SmartEntityCollection<InvoiceLineItem> Items { get; private set; } //* = new SmartEntityCollection<InvoiceLineItem>();

        #endregion

        #region Fields and Constants

        [AutoField]
        public ISmartField<string> InvoiceDate { get; private set; } //* = new SmartField<string>();

        [AutoField]
        public ISmartField<Guid> InvoiceID { get; private set; } //* = new SmartField<Guid>();
        [AutoField]
        public ISmartField<string> InvoiceNumber { get; private set; } //* = new SmartField<string>();
        [AutoField]
        public ISmartField<decimal> InvoiceTotal { get; private set; } //* = new SmartField<decimal>();
        [AutoField]
        public ISmartField<decimal> ItemsTotalPrice { get; private set; } //* = new SmartField<decimal>();

        [AutoField]
        public ISmartField<decimal> ItemsTotalTax { get; private set; } //* = new SmartField<decimal>();
        [AutoField]
        public ISmartField<decimal> ItemsTotalWeight { get; private set; } //* = new SmartField<decimal>();
        [AutoField]
        public ISmartField<decimal> Shipping { get; private set; } //* = new SmartField<decimal>();
        [AutoField]
        public ISmartField<decimal> ShippingRate { get; private set; } //* = new SmartField<decimal>();
        [AutoField]
        public ISmartField<decimal> TaxRate { get; private set; } //* = new SmartField<decimal>();

        #endregion
    }
}